using ERP.Domain.Warehouse.Allocation;
using Repository.communal;
using SqlSugar;

namespace Warehouse.Repository
{
    /// <summary>
    /// 调拨单仓储实现
    /// </summary>
    public class AllocationRepository : BaseRepository<TransferOrder>, IAllocationRepository
    {
        private readonly ISqlSugarClient _db;

        public AllocationRepository(MyDbContext context, ISqlSugarClient db) : base(context)
        {
            _db = db;
        }

        public async Task<string> GetNextTransferNoAsync()
        {
            var today = DateTime.Now.ToString("yyyyMMdd");
            var prefix = $"DB{today}";

            // 查询当天最大的调拨单号
            var maxNo = await _db.Queryable<TransferOrder>()
                .Where(x => x.TransferNo.StartsWith(prefix))
                .OrderByDescending(x => x.TransferNo)
                .Select(x => x.TransferNo)
                .FirstAsync();

            if (string.IsNullOrEmpty(maxNo))
            {
                return $"{prefix}001";
            }

            // 提取序号部分并递增
            var sequencePart = maxNo.Substring(prefix.Length);
            if (int.TryParse(sequencePart, out int sequence))
            {
                return $"{prefix}{(sequence + 1):D3}";
            }

            return $"{prefix}001";
        }

        public async Task<TransferOrder?> GetByTransferNoAsync(string transferNo)
        {
            return await _db.Queryable<TransferOrder>()
                .Where(x => x.TransferNo == transferNo)
                .FirstAsync();
        }

        public async Task<TransferOrder?> GetWithLinesAsync(int transferId)
        {
            return await _db.Queryable<TransferOrder>()
                .Where(x => x.Id == transferId)
                .FirstAsync();
        }

        public async Task InsertLinesAsync(List<TransferOrderLine> lines)
        {
            await _db.Insertable(lines).ExecuteCommandAsync();
        }

        public async Task<List<TransferOrderLine>> GetLinesAsync(int transferId)
        {
            return await _db.Queryable<TransferOrderLine>()
                .Where(x => x.TransferId == transferId)
                .OrderBy(x => x.LineNo)
                .ToListAsync();
        }

        public async Task<(List<TransferOrder> Data, int TotalCount)> GetPagedListAsync(
            int pageIndex, 
            int pageSize, 
            string? transferNo = null,
            int? fromWarehouseId = null,
            int? toWarehouseId = null,
            byte? billStatus = null,
            byte? outStatus = null,
            byte? inStatus = null,
            DateTime? beginDate = null,
            DateTime? endDate = null)
        {
            var query = _db.Queryable<TransferOrder>();

            // 应用筛选条件
            if (!string.IsNullOrEmpty(transferNo))
            {
                query = query.Where(x => x.TransferNo.Contains(transferNo));
            }

            if (fromWarehouseId.HasValue)
            {
                query = query.Where(x => x.FromWarehouseId == fromWarehouseId.Value);
            }

            if (toWarehouseId.HasValue)
            {
                query = query.Where(x => x.ToWarehouseId == toWarehouseId.Value);
            }

            if (billStatus.HasValue)
            {
                query = query.Where(x => x.BillStatus == billStatus.Value);
            }

            if (outStatus.HasValue)
            {
                query = query.Where(x => x.OutStatus == outStatus.Value);
            }

            if (inStatus.HasValue)
            {
                query = query.Where(x => x.InStatus == inStatus.Value);
            }

            if (beginDate.HasValue)
            {
                query = query.Where(x => x.ApplyDate >= beginDate.Value);
            }

            if (endDate.HasValue)
            {
                query = query.Where(x => x.ApplyDate <= endDate.Value.AddDays(1).AddSeconds(-1));
            }

            // 获取总数
            var totalCount = await query.CountAsync();

            // 分页查询
            var data = await query
                .OrderByDescending(x => x.CreatedAt)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            return (data, totalCount);
        }

        public async Task<TransferOrder?> GetDetailWithLinesAsync(int transferId)
        {
            return await _db.Queryable<TransferOrder>()
                .Where(x => x.Id == transferId)
                .FirstAsync();
        }

        public async Task InsertOutRecordsAsync(List<TransferOutRecord> outRecords)
        {
            await _db.Insertable(outRecords).ExecuteCommandAsync();
        }

        public async Task InsertInRecordsAsync(List<TransferInRecord> inRecords)
        {
            await _db.Insertable(inRecords).ExecuteCommandAsync();
        }

        public async Task<List<TransferOutRecord>> GetOutRecordsAsync(int transferId)
        {
            return await _db.Queryable<TransferOutRecord>()
                .Where(x => x.TransferId == transferId)
                .OrderBy(x => x.OperatedAt)
                .ToListAsync();
        }

        public async Task<List<TransferInRecord>> GetInRecordsAsync(int transferId)
        {
            return await _db.Queryable<TransferInRecord>()
                .Where(x => x.TransferId == transferId)
                .OrderBy(x => x.OperatedAt)
                .ToListAsync();
        }

        public async Task UpdateTransferStatusAsync(int transferId, byte? billStatus = null, byte? outStatus = null, byte? inStatus = null)
        {
            // 使用 SqlSugar 的 Updateable，避免表名大小写或复数命名不一致导致的错误
            var updater = _db.Updateable<TransferOrder>()
                .Where(x => x.Id == transferId)
                .SetColumns(x => new TransferOrder { UpdatedAt = DateTime.Now });

            if (billStatus.HasValue)
            {
                updater = updater.SetColumns(x => new TransferOrder { BillStatus = billStatus.Value });
            }

            if (outStatus.HasValue)
            {
                updater = updater.SetColumns(x => new TransferOrder { OutStatus = outStatus.Value });
            }

            if (inStatus.HasValue)
            {
                updater = updater.SetColumns(x => new TransferOrder { InStatus = inStatus.Value });
            }

            await updater.ExecuteCommandAsync();
        }

        public async Task UpdateLineOutQtyAsync(int lineId, decimal outQty)
        {
            await _db.Updateable<TransferOrderLine>()
                .SetColumns(x => new TransferOrderLine { OutQty = outQty, UpdatedAt = DateTime.Now })
                .Where(x => x.Id == lineId)
                .ExecuteCommandAsync();
        }

        public async Task UpdateLineInQtyAsync(int lineId, decimal inQty)
        {
            await _db.Updateable<TransferOrderLine>()
                .SetColumns(x => new TransferOrderLine { InQty = inQty, UpdatedAt = DateTime.Now })
                .Where(x => x.Id == lineId)
                .ExecuteCommandAsync();
        }
    }
}
